using System;
using System.Collections.Generic;

using FineCollection.Intf;




namespace FineCollection.NV
{
    /// <summary>
    /// Adapter for the native dictionary (the <see cref="Dictionary{TKey,TValue}"/> container).
    /// </summary>
    /// <stereotype>container</stereotype>
    public class NvHashMap<K,V> : RMap<K,V>
        where K: IEquatable<K>
    {
        /// <summary>
        /// The native dictionary this class adapts.
        /// </summary>
        /// <remarks>
        /// Not null.
        /// </remarks>
        public readonly Dictionary<K,V> dict;


        /// <summary>
        /// Creates an adapter for the specified native dictionary.
        /// </summary>
        /// <param name="dict">the dictionary to adapt.</param>
        public NvHashMap(Dictionary<K,V> dict)
        {
            if (dict == null)
                throw new NullReferenceException("Passed null dictionary to NvHashMap.");

            this.dict = dict;
        }


        /// <summary>
        /// Count of items in the list.
        /// </summary>
        public int Count
        {
            get { return dict.Count; }
        }

        /// <summary>
        /// Checks whether the collection is empty.
        /// </summary>
        public bool IsEmpty
        {
            get { return dict.Count == 0; }
        }

        /// <summary>
        /// Checks whether the map has at least one item.
        /// </summary>
        public bool IsNotEmpty
        {
            get { return dict.Count > 0; }
        }


        /// <summary>
        /// Checks whether this map contains a pair with the specified key.
        /// </summary>
        /// <para>
        /// Complexity of this function is close to <b>O(1)</b>.
        /// </para>
        /// <param name="key">the key to check.</param>
        /// <returns>true - the specified key is in the map.</returns>
        public bool ContainsKey(K key)
        {
            return dict.ContainsKey(key);
        }


        public V Find(K key, V notFound)
        {
            V value;
            bool found =
                dict.TryGetValue(key, out value);
            if (found)
                return value;
            else
                return notFound;
        }


        public V this[K key]
        {
            get { return Find(key, default(V)); }
        }


        public MapEntry<K,V>[] ListAllEntries()
        {
            int i = 0, n = dict.Count;
            MapEntry<K,V>[] entries = new MapEntry<K, V>[n];
            foreach (var entry in dict)
                entries[i++] = new MapEntry<K,V>(entry.Key, entry.Value);
            return entries;
        }


    }
}